﻿#include "common_tool.h"
#include "common_log.h"
#include <QDataStream>
#include <QTimer>

bool StatusThread::Init(const QString& ip, const int port)
{
	m_ip = ip;
	m_port = port;
	return true;
}

void StatusThread::Stop()
{
	m_running = false;

	if (m_socket && m_socket->IsConnected()) {
		m_socket->DisConnected();
	}
	quit();
	wait();
	log_trace("Status Thread stoped");
}

#define TIMEOUT (1000)

void StatusThread::run()
{
	if (m_socket == nullptr) {
		m_socket = new TCPClient(nullptr);
	}
	connect(m_socket, &TCPClient::ReceievedData, this, &StatusThread::OnReceievedData, Qt::DirectConnection);
	connect(m_socket, &TCPClient::TcpDisconnected, this, &StatusThread::OnDisConnected);
	m_timer = new QTimer;
	m_timer->setSingleShot(true);
	connect(m_timer, &QTimer::timeout, this, &StatusThread::OnStatusReciveTimeout, Qt::DirectConnection);
	connect(m_socket, &TCPClient::ReceievedData, this, [&]() {
		if (m_timer->isActive()) {
			m_timer->stop();
			m_timer->start(TIMEOUT);
		}
		});
	if (!m_socket->ConnectToHost(m_ip, m_port)) {
		cleanupResources();
		emit connectionStatusChanged(1);
		log_trace("状态端口连接失败");
		return;
	}
	if (m_socket->WaitForConnected(5000)) {
		log_trace("状态端口连接成功");
		emit connectionStatusChanged(0);
		m_timer->start(TIMEOUT);
	} else {
		cleanupResources();
		emit connectionStatusChanged(1);
		log_trace("状态端口连接失败");
		return;
	}

	m_running = true;

	exec();
	cleanupResources();
}

void StatusThread::cleanupResources()
{
	if (m_timer) {
		m_timer->stop();
		m_timer->deleteLater();
		m_timer = nullptr;
	}
	if (m_socket) {
		if (m_socket->IsConnected()) {
			m_socket->DisConnected();
		}
		m_socket->deleteLater();
		m_socket = nullptr;
	}

}

void StatusThread::OnDisConnected()
{
	log_trace("状态端口连接断开");
	emit connectionStatusChanged(1);
}
void StatusThread::OnReceievedData(const QByteArray& data)
{
	emit statusUpdated(data);
}

void StatusThread::OnStatusReciveTimeout()
{
	if (!m_running) return;
	if (m_socket) {	// 断开连接后，重连
		m_socket->DisConnected();
		log_trace("IP:{}, PORT:{}断开连接，尝试重连....", m_ip, m_port);
		if (m_socket->ConnectToHost(m_ip, m_port)) {
			if (m_socket->WaitForConnected(5000)) {
				log_trace("重连成功");
				m_timer->start(TIMEOUT);
			}
		} else {
			log_trace("尝试重新连接恢复异常失败");
			emit connectionStatusChanged(3);
			quit();
		}
	}

}

unsigned int FromBinToInt(const QByteArray& d)
{
	unsigned int ret = 0;
	for (int index = d.length(); index > 0; index--) {
		ret *= 1 << 8;
		ret += (unsigned char)d.at(index - 1);
	}

	return ret;
}
QByteArray ToBin(int val, int size)
{
	QByteArray ret;
	ret.resize(size);
	unsigned char f = 0xff;
	for (int i = 0; i < size; i++) {
		ret[i] = (val >> i * 8) & f;
	}
	return ret;
}

QByteArray ToBin(float vale, int size)
{
	return QByteArray::fromRawData((const char*)&vale, size);
}

float FromBinToFloat(const QByteArray& d)
{
	if (d.size() != 4) {
		return 0.0f;
	}
	float val = 0.0f;
	QDataStream stream(d);
	stream.setByteOrder(QDataStream::LittleEndian);
	stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
	stream >> val;
	return ((float)((int)val * 100)) / 100;
}

QString FromBinToString(const QByteArray& d)
{
	QString ret;
	for (auto i : d) {
		unsigned char f = 0x01;
		while (f) {
			ret.append(i & f ? "1" : "0");
			f = f << 1;
		}
	}
	return ret;
}

